package com.da.javatest.interview.session2;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author chenlida
 * @date 2020/3/29 15:10
 * @description ABA问题
 */
public class Test06ABA {
    private static AtomicInteger ai = new AtomicInteger(5);
    private static AtomicStampedReference<Integer> asr = new AtomicStampedReference(5, 1);

    public static void main(String[] args) {
        new Thread(() -> {
            ai.compareAndSet(5, 10);
            ai.compareAndSet(10, 5);
        }, "t1").start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(ai.compareAndSet(5, 101) + " " + ai.get());
        }, "t2").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("===============ABA问题解决===============");
        new Thread(() -> {
            int stamp = asr.getStamp();
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + stamp);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            asr.compareAndSet(5, 10, asr.getStamp(), asr.getStamp() + 1);
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + asr.getStamp());
            asr.compareAndSet(10, 5, asr.getStamp(), asr.getStamp() + 1);
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + asr.getStamp());
        }, "t3").start();

        new Thread(() -> {
            int stamp = asr.getStamp();
            System.out.println(Thread.currentThread().getName() + "当前版本号:" + stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(asr.compareAndSet(5, 1024, stamp, stamp + 1) + " " + asr.getReference());
        }, "t4").start();

    }
}
